/*
 * Cloud9 Parallel Symbolic Execution Engine
 *
 * Copyright (c) 2011, Dependable Systems Laboratory, EPFL
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Dependable Systems Laboratory, EPFL nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE DEPENDABLE SYSTEMS LABORATORY, EPFL BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * All contributors are listed in CLOUD9-AUTHORS file.
 *
*/

#include "cloud9/worker/ComplexStrategies.h"

namespace cloud9 {

namespace worker {

////////////////////////////////////////////////////////////////////////////////
// Composed Strategy
////////////////////////////////////////////////////////////////////////////////

ComposedStrategy::ComposedStrategy(std::vector<StateSelectionStrategy*> &_underlying) : underlying(_underlying) {
    assert(underlying.size() > 0);
}

ComposedStrategy::~ComposedStrategy() {

}

void ComposedStrategy::onStateActivated(SymbolicState *state) {
    for (strat_vector::iterator it = underlying.begin(); it != underlying.end(); it++) {
        StateSelectionStrategy *strat = *it;
        strat->onStateActivated(state);
    }
}

void ComposedStrategy::onStateUpdated(SymbolicState *state, WorkerTree::Node *oldNode) {
    for (strat_vector::iterator it = underlying.begin(); it != underlying.end(); it++) {
        StateSelectionStrategy *strat = *it;
        strat->onStateUpdated(state, oldNode);
    }
}

void ComposedStrategy::onStateDeactivated(SymbolicState *state) {
    for (strat_vector::iterator it = underlying.begin(); it != underlying.end(); it++) {
        StateSelectionStrategy *strat = *it;
        strat->onStateDeactivated(state);
    }
}

////////////////////////////////////////////////////////////////////////////////
// Time Multiplexed Strategy
////////////////////////////////////////////////////////////////////////////////


TimeMultiplexedStrategy::TimeMultiplexedStrategy(std::vector<StateSelectionStrategy*> strategies) :
    ComposedStrategy(strategies), position(0) {

}

TimeMultiplexedStrategy::~TimeMultiplexedStrategy() {

}

SymbolicState* TimeMultiplexedStrategy::onNextStateSelection() {
  SymbolicState *state = underlying[position]->onNextStateSelection();

  position = (position + 1) % underlying.size();

  return state;
}

}

}
